import {
	DEViewActionType,
	IActionResult,
	IContext,
	IDECtrlAbility,
	IDEViewAbility,
	IDEViewController,
	IDEViewControllerParams,
	IDEViewStore,
	IParam,
	IViewActionResult,
	IViewDetail,
	IViewModel,
} from '@/core/interface';
import { AuthUtil, computedNavData, deepCopy } from '@/core/utils';
import { ViewController } from './view-controller';

/**
 * 实体视图控制器
 *
 * @export
 * @class DEViewController
 * @extends {ViewController<T, S, A>}
 * @template T 视图行为接口
 * @template S 视图仓库数据接口
 * @template A 视图能力接口
 */
export class DEViewController<
		T,
		S extends IDEViewStore,
		A extends IDEViewAbility
	>
	extends ViewController<T | DEViewActionType, S, A>
	implements IDEViewController<S, A>
{
	/**
	 * 处理视图初始化
	 *
	 * @protected
	 * @param {IDEViewControllerParams<T, A>} params
	 * @memberof DEViewController
	 */
	protected processViewInit(params: IDEViewControllerParams<T, A>) {
		super.processViewInit(params);
		Object.assign(this.store, {
			openView: this.openData.bind(this),
			newView: this.newData.bind(this),
		});
	}

	/**
	 * 打开数据
	 *
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} data
	 * @return {*}
	 * @memberof DEViewController
	 */
	public async openData(context: IContext, viewParams: IParam, data: IParam[]) {
		const _data = data.length > 0 ? data[data.length - 1] : {};
		const openDataModel = this.getModel<IViewModel>().openData;
		if (!openDataModel) {
			App.getNotificationHelper().warning(
				App.ts('app.notificationtitle.warn', '警告'),
				App.ts('app.common.noconfigmainview', '未配置主数据视图')
			);
			return;
		}
		const {
			redirectView,
			redirectParam,
			openDataViewName,
			navContext,
			navViewParam,
			deCodeName,
			multiFormDEField,
			indexTypePSDEField,
		} = openDataModel;
		if (deCodeName && _data[deCodeName.toLowerCase()]) {
			Object.assign(context, {
				[deCodeName.toLowerCase()]: _data[deCodeName.toLowerCase()],
			});
		}
		const _context = deepCopy(context);
		const _viewParams = deepCopy(viewParams);
		if (navContext) {
			const navData = computedNavData(_data, context, viewParams, navContext);
			navData && Object.assign(_context, navData);
		}
		if (navViewParam) {
			const navData = computedNavData(_data, context, viewParams, navViewParam);
			navData && Object.assign(_viewParams, navData);
		}
		let view: IViewDetail = App.getAppViewConfig()?.[openDataViewName];
		// 适配实体属性配置多表单
		if (multiFormDEField) {
			const srfwizardvalue = _data[multiFormDEField];
			const tempViews: IParam = App.getAppViewConfig();
			const editView =
				tempViews &&
				Object.values(tempViews).find(
					(item: IParam) =>
						Object.is(item.funcViewParam, srfwizardvalue) &&
						Object.is(item.funcViewMode, 'EDITVIEW')
				);
			if (editView) {
				view = editView;
			}
		}
		// 适配实体属性配置索引类型属性
		if (indexTypePSDEField) {
			const srfwizardvalue = _data[indexTypePSDEField];
			const tempViews: IParam = App.getAppViewConfig();
			const editView =
				tempViews &&
				Object.values(tempViews).find(
					(item: IParam) =>
						Object.is(item.funcViewParam, srfwizardvalue) &&
						Object.is(item.funcViewMode, 'EDITVIEW')
				);
			if (editView) {
				view = editView;
			}
		}
		//  todo 工作流已读标记
		if (redirectView) {
			if (redirectParam.minorDERSs && redirectParam.minorDERSs.length > 0) {
				redirectParam.minorDERSs.forEach((minor: any) => {
					if (
						minor.parentDeField &&
						minor.majorDeCodeName &&
						_data[minor.parentDeField.toLowerCase()] &&
						!_context[minor.majorDeCodeName.toLowerCase()]
					) {
						Object.assign(_context, {
							[minor.majorDeCodeName.toLowerCase()]:
								_data[minor.parentDeField.toLowerCase()],
						});
					}
				});
			}
			const UIService = await App.getUIService(deCodeName, context);
			const response = await UIService.getAppRDView(
				_context,
				_viewParams,
				_data,
				{
					isEnableWorkflow: false,
					redirectAction: redirectParam.redirectAction,
				}
			);
			if (response && response.viewName) {
				view = App.getAppViewConfig()?.[response.viewName];
			}
		}
		if (view) {
			const result: IActionResult | void =
				await App.getOpenViewHelper().openPage(view, _context, _viewParams);
			if (result && result.ok && result.data && result.data.length > 0) {
				this.refreshRootView();
			}
		} else {
			App.getNotificationHelper().error(
				App.ts('app.notificationtitle.error'),
				App.ts('app.common.noeditview')
			);
		}
	}

	/**
	 * 新建数据
	 *
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} data
	 * @return {*}
	 * @memberof DEViewController
	 */
	public async newData(context: IContext, viewParams: IParam, data: IParam[]) {
		const _data = data.length > 0 ? data[data.length - 1] : {};
		const newDataModel = this.getModel<IViewModel>().newData;
		if (!newDataModel) {
			App.getNotificationHelper().warning(
				App.ts('app.notificationtitle.warn', '警告'),
				App.ts('app.common.noconfignewview', '未配置新建数据视图')
			);
			return;
		}
		const {
			enableWizardAdd,
			enableBatchAdd,
			batchAddOnly,
			newDataViewName,
			deCodeName,
			navContext,
			navViewParam,
		} = newDataModel;
		if (enableWizardAdd) {
			// 打开向导视图
			this.openWizardView(context, viewParams, data, _data, newDataModel);
		} else if (enableBatchAdd) {
			// todo
		} else if (batchAddOnly) {
			// todo
		} else if (newDataViewName) {
			const _context = deepCopy(context);
			const _viewParams = deepCopy(viewParams);
			// 新建视图且不是拷贝模式时 删除上下文主键信息
			if (
				deCodeName &&
				_context[deCodeName.toLowerCase()] &&
				!viewParams.copymode
			) {
				delete _context[deCodeName.toLowerCase()];
			}
			if (navContext) {
				const navData = computedNavData(data, context, viewParams, navContext);
				navData && Object.assign(_context, navData);
			}
			if (navViewParam) {
				const navData = computedNavData(
					_data,
					context,
					viewParams,
					navViewParam
				);
				navData && Object.assign(_viewParams, navData);
			}
			const view: IViewDetail = App.getAppViewConfig()?.[newDataViewName];
			if (view) {
				const result: IActionResult | void =
					await App.getOpenViewHelper().openPage(view, _context, _viewParams);
				if (result && result.ok && result.data && result.data.length > 0) {
					this.refreshRootView();
				}
			} else {
				App.getNotificationHelper().error(
					App.ts('app.notificationtitle.error'),
					App.ts('app.common.nonewview')
				);
			}
		}
	}
	/**
	 * 计算工具栏权限状态
	 *
	 * @protected
	 * @param {IParam} data
	 * @memberof MDViewController
	 */
	protected async calcToolbarItemAuthState(data: IParam) {
		if (this.model.entityCodeName) {
			const UIService = await App.getUIService(
				this.model.entityCodeName,
				this.store.context
			);
			AuthUtil.calcToolbarItemAuthState(
				data,
				this.store.toolbarItems,
				UIService,
				this.model
			);
		}
	}

	/**
	 * 加载视图
	 *
	 * @memberof DEViewController
	 */
	public load(args?: IParam): Promise<IViewActionResult> {
		if (this.model.xDataCtrlName) {
			const ability = this.getSubAbility<IDECtrlAbility>(
				this.model.xDataCtrlName
			);
			if (ability) {
				return ability.load(args);
			}
		}
		return Promise.resolve({ ok: false, rowData: {}, data: [] });
	}

	/**
	 * 打开向导添加视图
	 *
	 * @memberof DEViewController
	 */
	public async openWizardView(
		context: IContext,
		viewParams: IParam,
		data: IParam[],
		_data: IParam,
		newDataModel: IParam
	) {
		const { wizardPSAppView, deCodeName, navContext, navViewParam } =
			newDataModel;
		const _context = deepCopy(context);
		const _viewParams = deepCopy(viewParams);
		// 新建视图且不是拷贝模式时 删除上下文主键信息
		if (
			deCodeName &&
			_context[deCodeName.toLowerCase()] &&
			!viewParams.copymode
		) {
			delete _context[deCodeName.toLowerCase()];
		}
		if (navContext) {
			const navData = computedNavData(data, context, viewParams, navContext);
			navData && Object.assign(_context, navData);
		}
		if (navViewParam) {
			const navData = computedNavData(_data, context, viewParams, navViewParam);
			navData && Object.assign(_viewParams, navData);
		}
		const wizardView: IViewDetail = App.getAppViewConfig()?.[wizardPSAppView];
		if (!wizardView) {
			console.warn(App.ts('app.common.nonewview', '新建视图不存在'));
			return;
		}
		const result = await App.getOpenViewHelper().openPage(
			wizardView,
			_context,
			_viewParams
		);
		if (result && result.ok && result.data && result.data.length > 0) {
			const { srfkey } = result.data[0];
			const tempViews: any = App.getAppViewConfig();
			const editView: any =
				tempViews &&
				Object.values(tempViews).find(
					(item: any) =>
						Object.is(item.funcViewParam, srfkey) &&
						Object.is(item.funcViewMode, 'EDITVIEW')
				);
			if (editView) {
				// 向导添加支持附加参数
				Object.assign(_viewParams, { srfwizardvalue: srfkey });
				const result2 = await App.getOpenViewHelper().openPage(
					editView,
					_context,
					_viewParams
				);
				if (result2 && result2.ok && result2.data && result2.data.length > 0) {
					this.refreshRootView();
				}
			}
		}
	}
}
